Caliandro.de - Blog

Fediverse GoToSocial Bot zur Weiterleitung von Website News erstellen

Bot Definition im Kontext des Fediverse

Ein automatisch gesteuertes Programm, dass einen oder mehrere Aufgaben erfüllt und im Ergebnis eine Fediverse Nachricht verfasst. Beispiele:

  • Wetterbenachrichtigungen
  • Informationen von Websiten weitergeben
  • Informationen von öffentlichen Services weitergeben (z.B. Warnmeldungen des Katastrophenschutzes)
  • Zufällige Texte posten (Zitate, Witze …)
  • ETL Jobs (Extract, Transform, Load): Daten holen, manipulieren/berechnen/in Beziehung zu anderen Daten setzen und sie in das Zielsystem (Fediverse) laden

Mein Use Case

Für Zöliakie-Betroffene gibt es die Deutsche Zöliakie Gesellschaft (DZG), ein Verein, der Lobby, Informationen und Selbsthilfe bei Glutenunverträglichkeit organisiert. Leider ist die DZG wie viele Vereine und Instiutionen auch (noch) nicht im Fediverse aktiv. Bis es soweit ist, will ich mit meinem (Beispiel-) Bot Neuigkeiten der DZG ins Fediverse weiterleiten.

Was wird für den Bot benötigt?

  • Grundlagen Wissen der Programmierung und von HTML
  • Eine Fediverse Instanz, auf der man einen Bot betreiben kann (für andere Plattformen wie Mastodon müßte alles bis auf den API Call passen)
  • Einen dauerhaft mit dem Web verbundenen Server (VPS, RaspberryPi etc.), der zu geplanten Uhrzeiten ein PHP-Skript ausführen kann

Anleitung

Zusammengefasst besteht das gesamte Konstrukt aus folgenden Prozesse

  1. Website Daten auslesen (Web Scraping)
  2. Die passenden Informationen identifizieren und aufbereiten
  3. Diese Informationen als neuer Fediverse Status (=Nachricht) veröffentlichen

Grobe Schritt-für-Schritt-Anleitung

  1. Inspektion der Website: Welche Tags werden im Quellcode bei Newseinträgen verwendet?
  2. Python Script Teil 1 (Beautiful Soup)

    Sollte alle gefundenen Elemente testweise in der Shell ausgeben. Hinweis: Das folgende Skript ist bewusst simpel gehalten

    import requests
    
    from bs4 import BeautifulSoup
    from datetime import datetime
    
    dateFormatter = "DATE_FORMAT_USED_ON_WEBSITE"
    
    url = "URL_WITH_CONTENT_TO_SCRAPE"
    response = requests.get(url)
    if response.status_code == requests.codes.ok:
      html_content = response.text
      print("Request was successful!")
      soup = BeautifulSoup(html_content, 'html.parser')
      mydivs = soup.find_all("div", {"class": "slider_textcontainer"})
      for mydiv1 in mydivs:
    
        title_element = mydiv1.find("h2")
        content_element = mydiv1.find("p")
        time_element=datetime.strptime(mydiv1.find("time").text, dateFormatter)
    
        print(title_element.text)
        print(mydiv1.find("time").text)
        print(content_element.text)
        print("==========")
    
    else:
      print("Failed to retrieve data. Status code: response.status_code}")
    
  3. GoToSocial Account anlegen

    Da GoToSocial noch in der Entwicklung ist, gibt es im Admin Backend noch keine einfache Möglichkeit, einen neuen Account anzulegen. Hierzu ist Zugriff auf den Server gefragt (in meinem Beispiel auf einem Debian Yunohost Server):

    . /var/www/gotosocial
    ./gotosocial admin account create --username USERNAME --email ACCOUNT@EMAIL.DE --password SECRET_PASSWORD --config-path config.yaml
    
  4. Bearer Token auslesen

    Geht etwas aufwändiger mit einem Rest Tool (und der GTS API Doku) oder einfacher über einen Service wie https://takahashim.github.io/mastodon-access-token/ (dem man dann allerdings Vertrauen können muss)

  5. Python Script Teil 2 (inkl. Fediverse Status erstellen)

    Hinweis: Auch dieses Skript ist bewusst simpel gehalten und würde je nach Ausführungshäufigkeit doppelte Einträge erzeugen oder Neuigkeiten verpassen

    ...
    for mydiv1 in mydivs:
       title_element = mydiv1.find("h2")
       content_element = mydiv1.find("p")
       time_element=datetime.strptime(mydiv1.find("time").text, dateFormatter)
    
       if time_element.date() == datetime.now().date():
    
    	    #POSTING A STATUS TO THE FEDIVERSE
    	  requests.post(
    	     url="URL_OF_GO_TO_SOCIAL_INSTANCE/api/v1/statuses",
    	     headers={"Authorization": "Bearer TOKEN"},
    	       json={"status":title_element.text+" (Datum:"+mydiv1.find("time").text+
    	       ")\n\n"+content_element.text+"\n#YOUR_HASHTAGS","visibility": "public"},
    	       )
       else:
    	  print ("Older entries found:" +str(time_element))
    	  ...	 
    
  6. Script auf dem Server platzieren und manuell ausführen
  7. Cronjob erstellen

    In meinem Beispielskript wird nur abgeprüft, ob das Datum des Newseintrags einer Website dem heutigen Datum entspricht. Daher dürfte das Skript nur 1x täglich ablaufen, möglichst um eine Uhrzeit, bei der keine neuen Nachrichten mehr zu erwarten sind

  8. Optimieren

    In meinem Fall habe ich die Erkennung neuer Einträge erweitert, in dem die bisher gefundenen und weitergeleiteten Nachrichten Titel in einem Textfile gespeichert werden. Dieses File wird dann bei jedem Lauf auf Dubletten iteriert und nur wirklich neue Einträge werden weitergeleitet. Dadurch kann das Script jetzt öfters am Tag laufen.